module test
    implicit none
contains
    subroutine sort_int(a,n)
        integer,intent(in)::n
        integer,intent(inout)::a(n)
        integer::b1(n,0:1)
        integer::i,j,num(0:1),k
        do j=0,30
            num=0
            do i=1,n
                k=merge(1, 0, btest(a(i),j))
                num(k)=num(k)+1
                b1(num(k),k)=a(i)
            end do
            a(1:num(0))=b1(1:num(0),0)
            a(num(0)+1:)=b1(1:num(1),1)
        end do
        num=0
        j=31
        do i=1,n
            k=merge(0, 1, btest(a(i),j))
            num(k)=num(k)+1
            b1(num(k),k)=a(i)
        end do
        a(1:num(0))=b1(1:num(0),0)
        a(num(0)+1:)=b1(1:num(1),1)
    end subroutine

    subroutine sort_float(a,n)
        integer,intent(in)::n
        real,intent(inout)::a(n)
        integer::a0(n)
        a0=transfer(a,1,n)
        call bsort_float(a0,n)
        a=transfer(a0,1.0,n)
    end subroutine

    subroutine bsort_float(a,n)
        integer,intent(in)::n
        integer,intent(inout)::a(n)
        integer::b1(n,0:1)
        integer::i,j,num(0:1),k
        do j=0,30
            num=0
            do i=1,n
                !k=mod(rshift(a(i),j),2)
                k=merge(1, 0, btest(a(i),j))
                num(k)=num(k)+1
                b1(num(k),k)=a(i)
            end do
            a(1:num(0))=b1(1:num(0),0)
            a(num(0)+1:)=b1(1:num(1),1)
        end do
        num=0
        j=31
        do i=1,n
            !k=mod(rshift(a(i),j),2)
            k=merge(1, 0, btest(a(i),j))
            num(k)=num(k)+1
            b1(num(k),k)=a(i)
        end do
        a(1:num(1))=b1(num(1):1:-1,1)
        a(num(1)+1:)=b1(1:num(0),0)
    end subroutine

end module

program main
    use test
    implicit none
    integer,parameter::n=10
    integer::a(n)=[1,3,-4,-2,5,100,-234,111,555,777]
    real::b(n)
    call random_number(b)
    b=b-0.5
    write(*,*)"sort_float:"
    write(*,"(*(F10.4))")b
    call sort_float(b,n)
    write(*,"(*(F10.4))")b
    write(*,*)"sort_int:"
    write(*,"(*(I10))")a
    call sort_int(a, n)
    write(*,"(*(I10))")a
end program
